package com.duneyr.snakes.generate;

import java.util.Random;

import com.duneyr.snakes.Level;

public interface GenMap {
	/**
	 * Attempts to place a Large room. A large room may consist of
	 * two or more (joined) rectangles.
	 * Will retry up to 5 times if the room overlaps other rooms,
	 * before stopping.
	 * @param random for random numbers
	 */
	void addRandomLargeRoom(Random random);
	
	/**
	 * Attempts to place a Large room. A large room may consist of
	 * two or more (joined) rectangles.
	 * @param random for random numbers
	 * @param nRetry if the random room overlaps,
	 * how many times should this method retry at placing a room?
	 * before stopping
	 */
	void addRandomLargeRoom(Random random, int nRetry);
	
	/**
	 * Add a simple rectangular room. Will retry up to 5 times.
	 * @param random for random numbers
	 */
	void addRandomRoom(Random random);

	/**
	 * Add a simple rectangular room. Will retry up to nRetry times.
	 * @param random for random numbers
	 * @param nRetry the maximum numbers of retries.
	 */
	void addRandomRoom(Random random, int nRetry);
	
	/**
	 * Get one of the rooms on this map.
	 * @return a room.
	 */
	GenRoom getRandomRoom(Random random);
	
	/**
	 * Connects the two rooms r1 and r2 if not already connected by a corridor.
	 * If room r2 is already connected to r3 when the connection r1-r2 has been
	 * made, r3 is considered to be connected to r1 and r1 to r3, thus a call
	 * connect(r1,r3) could do nothing.
	 * (But it may add a direct connection r1-r3 if possible).
	 * Will attempt to connect through other rooms if necessary.
	 * @param r1 room one.
	 * @param r2 room two.
	 */
	void connect(GenRoom r1, GenRoom r2);
	
	/**
	 * Returns an collection or array or Iterable
	 * of some sort that allows for iteration of all the rooms
	 * @return Iterable covering all the rooms
	 */
	Iterable<GenRoom> rooms();

	/**
	 * Fill empty areas next to corridors.
	 */
	void roomFill();

	/**
	 * Fill all rooms and corridors with decorations.
	 */
	void decorate();

	/**
	 * Turn into a level object.
	 * @return
	 */
	Level toLevel();
}
